#include "pch.hpp"
#include "Project.hpp"

#include "Script.hpp"
#include "UiDefinition.hpp"
#include "Mesh.hpp"
#include "Material.hpp"

using namespace Engine;
using namespace Engine::Edit;




Project::Project(QString title, QFileInfo file)
	: ProjectItem(title)
	, m_file(file)

	, modified(m_modified)
{}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::post_create(ptr _this)
{
	__super::post_create(_this);

	if(!child("Scripts"))
		add(ProjectItem::create(_this, "Scripts"));

	if(!child("Ui Definitions"))
		add(ProjectItem::create(_this, "Ui Definitions"));

	if(!child("Materials"))
		add(ProjectItem::create(_this, "Materials"));

	if(!child("Meshes"))
		add(ProjectItem::create(_this, "Meshes"));
}
///////////////////////////////////////////////////////////////////////////////////////////////////




ProjectItem::Type Project::type() const
{
	return ProjectType;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

ProjectItem::ptr Project::scripts() const
{
	return child("Scripts");
}
///////////////////////////////////////////////////////////////////////////////////////////////////

ProjectItem::ptr Project::uiDefinitions() const
{
	return child("Ui Definitions");
}
///////////////////////////////////////////////////////////////////////////////////////////////////

ProjectItem::ptr Project::materials() const
{
	return child("Materials");
}
///////////////////////////////////////////////////////////////////////////////////////////////////

ProjectItem::ptr Project::meshes() const
{
	return child("Meshes");
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Project::load(AbstractDomInputStream& stream)
{
	stream.openElement("xml");
	stream.openElement("project");

	load<Script>(scripts(), "scripts", stream);
	load<UiDefinition>(uiDefinitions(), "ui", stream);
	load<Mesh>(meshes(), "meshes", stream);
	load<Material>(materials(), "materials", stream);

	stream.closeElement("project");
	stream.closeElement("xml");
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::save(AbstractDomOutputStream& stream) const
{
	stream.openElement("xml");
	stream.openElement("project");

	save(scripts(), "scripts", stream);
	save(uiDefinitions(), "ui", stream);
	save(meshes(), "meshes", stream);
	save(materials(), "materials", stream);

	stream.closeElement();
	stream.closeElement();
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::save(ProjectItem::const_ptr item, QString name, AbstractDomOutputStream& stream) const
{
	stream.openElement(name);
	stream.writeAttribute("count", item->numChildren());
	for(std::size_t i = 0; i < item->numChildren(); ++i)
		item->child(i)->save(stream);
	stream.closeElement();
}
///////////////////////////////////////////////////////////////////////////////////////////////////




ProjectItem::Result Project::emitModified(ProjectItem::weak_ptr sender, ProjectItem::weak_ptr item, Action action)
{
	return m_modified(sender, item, action);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

/*
QString Project::title() const
{
	return m_title;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::setTitle(QString title)
{
	m_title = title;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Project::Scripts Project::scripts() const
{
	return m_scripts;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool Project::hasScript(QString name) const
{
	foreach(Script::ptr script, m_scripts)
	{
		if(script->name() == name)
			return true;
	}

	return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Script::ptr Project::addScript()
{
	// Find a script name that is not used yet
	int number = 0;
	QString name;
	do
	{
		if(number == 0)
			name = QObject::tr("unnamed.as");
		else
			name = QObject::tr("unnamed%1.as").arg(number);

		++number;
	} while(hasScript(name));

	QDir dir = m_file.absoluteDir();
	if(!dir.cd("scripts"))
	{
		verify(dir.mkdir("scripts"));
		verify(dir.cd("scripts"));
	}

	auto script = boost::make_shared<Script>(dir, name);
	m_scripts.push_back(script);
	return script;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::remove(Script::ptr script)
{
	for(auto i = m_scripts.begin(); i != m_scripts.end(); ++i)
	{
		if(*i == script)
		{
			m_scripts.erase(i);
			return;
		}
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Project::UiDefinitions Project::uiDefinitions() const
{
	return m_uiDefinitions;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool Project::hasUiDefinition(QString name) const
{
	foreach(UiDefinition::ptr ui, m_uiDefinitions)
	{
		if(ui->name() == name)
			return true;
	}

	return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

UiDefinition::ptr Project::addUiDefinition()
{
	// Find a ui definition name that is not used yet
	int number = 0;
	QString name;
	do
	{
		if(number == 0)
			name = QObject::tr("unnamed.xml");
		else
			name = QObject::tr("unnamed%1.xml").arg(number);

		++number;
	} while(hasScript(name));

	auto ui = boost::make_shared<UiDefinition>(name);
	m_uiDefinitions.push_back(ui);
	return ui;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Project::remove(UiDefinition::ptr ui)
{
	for(auto i = m_uiDefinitions.begin(); i != m_uiDefinitions.end(); ++i)
	{
		if(*i == ui)
		{
			m_uiDefinitions.erase(i);
			return;
		}
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
*/
